/*
版权@hehung所有，转载请申明
email：1398660197@qq.com
*/
#include "app_oled.h"
#include "app_oled_Font.h"
#include <string.h>
#include <stdio.h>

void OLED_FillZone(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, e_OledColor color)
{
	uint8_t i;
	uint8_t j;
	
	if((x1 > x2) || (x1>=128) || (x2>=128))
		return;
	
	if((y1 > y2) || (y1>=64) || (y2>=64))
		return;
	
	for(i=x1; i<=x2; i++)
		for(j=y1; j<= y2; j++)
			OLED_DrawPoint(i, j, color);
}

//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//color:0,反白显示;1,正常显示				 
//size:选择字体 16/12 
void OLED_ShowChar(uint8_t x, uint8_t y, uint8_t chr, uint8_t size, e_OledColor color)
{      			    
	uint8_t temp, t, t1;
	uint8_t y0;
	uint8_t csize;

    y0 = y;
    csize = ((size>>3) + ((size%8)?1:0))*(size>>1);		//得到字体一个字符对应点阵集所占的字节数
	
	chr = chr - ' ';//得到偏移后的值		 
    for(t=0; t<csize; t++)
    {   
		if(12U == size) 
            temp=asc2_1206[chr][t]; 	 	//调用1206字体
		else if(16U == size)
            temp=asc2_1608[chr][t];	        //调用1608字体
		else if(24U == size)
            temp=asc2_2412[chr][t];	        //调用2412字体
		else if(36U == size)
			temp=asc2_3618[chr][t];
		else 
            return;								//没有的字库

        for(t1=0; t1<8; t1++)
		{
			if(temp & 0x80)
				OLED_DrawPoint(x, y, color);
			else 
                OLED_DrawPoint(x, y, !color);
			temp <<= 1;
			y++;
			if((y - y0) == size)
			{
				y = y0;
				x ++;
				break;
			}
		}  	 
    }          
}

//显示字符串
//x,y:起点坐标  
//size:字体大小 
//*p:字符串起始地址 
void OLED_ShowString(uint8_t x, uint8_t y, const uint8_t *p, uint8_t size, e_OledColor color)
{	
    while((*p<='~') && (*p>=' '))//判断是不是非法字符!
    {       
        if(x > (128 - (size / 2)))
		{
			x = 0;
			y += size;
		}
        if(y > (64-size))
		{
            x = 0;
            y = 0;
			OLED_Clear(OLED_FILL_BLACK);
		}
        OLED_ShowChar(x, y, *p, size, color);	 
        x += (size >> 1);
        p++;
    }  
}

//在指定位置显示一个汉字
//x:0~127
//y:0~63			 
//hz_c:输入汉字，汉字需要先建模
//color:0,反白显示;1,正常显示	
void OLED_ShowHz(uint8_t x, uint8_t y, const char hz_c[], e_OledColor color)
{
    uint8_t temp, t, t1;
    uint8_t y0 = y;
    uint8_t csize = 32u;
    uint8_t chr = 0;
	uint8_t flag = 0;

    for (t=0; t<(sizeof(hz_char)/sizeof(hz_char[0])); t++)
    {
        if(strcmp(hz_char[t], hz_c) == 0)
        {
            chr = t;
			flag = 1;    //找到了建模的汉字
            break;
        }
    }
	
	if(1 == flag)
	{
		chr <<= 1u;

		for(t=0; t<csize; t++)
		{
			if(16U == t)
				chr += 1;

			temp=(White == color) ? (hz_code[chr][t%16]):(~hz_code[chr][t%16]);

			for(t1=0; t1<8; t1++)
			{
				if(temp & 0x80)
					OLED_DrawPoint(x, y, White);
				else
					OLED_DrawPoint(x, y, Black);

				temp <<= 1;
				y++;
				if(16U == (y-y0))
				{
					y = y0;
					x++;
					break;
				}
			}
		}
	}
}

//显示连续的汉字,一行显示，一行128像素，最多显示8个
//hz_len: 要显示的函数的长度
//汉字大小为16像素，其他像素的汉字暂时不支持
//一个汉字的长度为三个字节，并且包含一个结束符
void OLED_ShowHzStringRow(uint8_t x, uint8_t y, const char *hz_s, e_OledColor color)
{
	uint8_t i;
	char chr[4];
	uint8_t len;
	
	len = strlen(hz_s);    //计算汉字字符串的长度
	
	for(i=0; i<(len-1); i+=3)
	{
		sprintf(chr, "%c%c%c", hz_s[i], hz_s[i+1], hz_s[i+2]);
		OLED_ShowHz(x+((i/3)<<4), y, chr, color);
	}
}

//显示连续的汉字，一列显示，一列64像素最多显示4个
//hz_len: 要显示的函数的长度
//汉字大小为16像素，其他像素的汉字暂时不支持
//一个汉字的长度为三个字节，并且包含一个结束符
void OLED_ShowHzStringColumn(uint8_t x, uint8_t y, const char *hz_s, e_OledColor color)
{
	uint8_t i;
	char chr[4];
	uint8_t len;
	
	len = strlen(hz_s);    //计算汉字字符串的长度

	for(i=0; i<(len-1); i+=3)
	{
		sprintf(chr, "%c%c%c", hz_s[i], hz_s[i+1], hz_s[i+2]);
		OLED_ShowHz(x, y+((i/3)<<4), chr, color);
	}
}

//在指定位置显示一个汉字
//x:0~127
//y:0~63			 
//chr:汉字的索引
//color:0,反白显示;1,正常显示	
void OLED_ShowHzFromIndex(uint8_t x, uint8_t y, uint8_t chr, e_OledColor color)
{
    uint8_t temp, t, t1;
    uint8_t y0 = y;
    uint8_t csize = 32u;

    chr <<= 1u;

    for(t=0; t<csize; t++)
    {
        if(16U == t)
            chr += 1;

        temp=(White == color) ? (hz_code[chr][t%16]):(~hz_code[chr][t%16]);

        for(t1=0; t1<8; t1++)
        {
            if(temp & 0x80)
                OLED_DrawPoint(x, y, White);
			else
				OLED_DrawPoint(x, y, Black);

            temp <<= 1;
            y++;
            if(16U == (y-y0))
            {
                y = y0;
                x++;
                break;
            }
        }
    }	  	
}

//OLED字符串连续显示函数
void OLED_HzStringFromIndex(uint8_t x, uint8_t y, uint8_t chr_S, uint8_t chr_E, e_OledColor color)
{
	uint8_t i;

	for(i=chr_S; i<=chr_E; i++)
	{
		OLED_ShowHzFromIndex(x+16*(i-chr_S), y, i, color); 	
	}
}

//m^n函数
uint32_t mypow(uint8_t m, uint8_t n)
{
	uint32_t result = 1;	 

	while(n--)
        result *= m;   

	return result;
}				  
//显示2个数字
//x,y :起点坐标	 
//len :数字的位数
//size:字体大小
//color:模式	0,填充模式;1,叠加模式
//num:数值(0~4294967295);	 		  
void OLED_ShowNum(uint8_t x, uint8_t y, uint32_t num, uint8_t len, uint8_t size, e_OledColor color)
{         	
	uint8_t t, temp;
	uint8_t enshow = 0;	

	for(t=0; t<len; t++)
	{
		temp = (num / mypow(10,len-t-1)) % 10;
		if((enshow == 0) && (t < (len-1)))
		{
			if(temp == 0)
			{
				OLED_ShowChar(x+(size/2)*t,y,'0',size, color);

				continue;
			}
            else 
                enshow = 1; 
		}
	 	OLED_ShowChar(x+(size/2)*t,y,temp+'0',size, color); 
	}
} 

void OLED_DrawBmpImg(uint8_t x,
					 uint8_t y,
					 const uint8_t bmp[][16],
					 uint32_t len,
					 e_OledColor color)
{
    uint16_t t, t1;
    uint8_t  y0 = y;
    uint8_t  temp = 0u;
    uint16_t len2 = (uint16_t)(len>>4u);

    for(t=0; t<len; t++)
    {
        temp=(White == color) ?
             (bmp[(uint8_t)(t/16)][(uint8_t)(t%16)]):(~bmp[(uint8_t)(t/16)][(uint8_t)(t%16)]);

        for(t1=0; t1<8; t1++)
        {
            if(temp & 0x80)
                OLED_DrawPoint(x, y, White);
			else
				OLED_DrawPoint(x, y, Black);

            temp <<= 1u;
            y++;
            if((y-y0) == len2)
            {
                y = y0;
                x ++;
                break;
            }
        }
    }
}

void OLED_DrawBmpImg2(uint8_t x,
					 uint8_t y,
					 const uint8_t bmp[][8],
					 uint32_t len,
					 uint8_t size,
					 e_OledColor color)
{
    uint16_t t, t1;
    uint8_t  y_end;
    uint8_t  temp;
    uint16_t len2 = 0u;

    y_end = y;

	len2 = (uint16_t)((len) / ((uint8_t)(size/8)));
//	if(size == 16)
//        len2 = (uint16_t)(len/2);
//    else if(size == 24)
//        len2 = (uint16_t)(len/3);
//    else if(size == 48)
//        len2 = (uint16_t)(len/6);
//    else if(size == 64)
//        len2 = (uint16_t)(len/8);

    for(t=0; t<len; t++)
    {
        temp=(White == color) ?
             (bmp[(uint8_t)(t/8)][(uint8_t)(t%8)]):(~bmp[(uint8_t)(t/8)][(uint8_t)(t%8)]);

        for(t1=0; t1<8; t1++)
        {
            if(temp&0x80)
                OLED_DrawPoint(x, y, White);
			else
				OLED_DrawPoint(x, y, Black);

            temp <<= 1u;
            y++;
            if((y-y_end) == len2)
            {
                y = y_end;
                x ++;
                break;
            }
        }
    }
}


 